package cn.com.infcn.spider.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;


/**
 * ftp util 
 * 
 * @author mixl
 *
 */
public class FtpUtil{
	
	private static final Logger LOG = Logger.getLogger(FtpUtil.class);
	
	private FTPClient ftpClient;
	
	private FtpConfiguration config;
	
	public FtpUtil(FtpConfiguration configuration) {
		this.config = configuration;
	}

	/**
	 * 
	 * 连接ftp服务器
	 * 
	 * @param server
	 *            服务器ip
	 * 
	 * @param port
	 *            端口，通常为21
	 * 
	 * @param user
	 *            用户名
	 * 
	 * @param password
	 *            密码
	 * 
	 * @param path
	 *            进入服务器之后的默认路径
	 * 
	 * @return 连接成功返回true，否则返回false
	 * 
	 * @throws SocketException
	 * 
	 * @throws IOException
	 */

	public boolean connectServer() throws SocketException, IOException {

		ftpClient = new FTPClient();

		ftpClient.connect(config.getServer(), config.getPort());

		ftpClient.setControlEncoding("UTF-8");
		
		if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {

			if (ftpClient.login(config.getUser(), config.getPassword())) {

				// Path is the sub-path of the FTP path

				if (config.getPath() != null && config.getPath().length() != 0) {

					ftpClient.changeWorkingDirectory(config.getPath());

				}

				return true;

			}

		}

		disconnect();

		return false;

	}

	/**
	 * 
	 * 断开与远程服务器的连接
	 * 
	 * @throws IOException
	 */

	public void disconnect() throws IOException {

		if (ftpClient.isConnected()) {

			ftpClient.disconnect();

		}

	}

	public boolean changeDirectory(String path) throws IOException {
		String encodedPath = new String(path.getBytes("utf-8"),"iso-8859-1");
		return ftpClient.changeWorkingDirectory(encodedPath);

	}

	/**
	 * 
	 * 查看目录是否存在
	 * 
	 * @param path
	 * 
	 * @return
	 * 
	 * @throws IOException
	 */

	public boolean isDirectoryExists(String path) throws IOException {

		boolean flag = false;

		FTPFile[] ftpFileArr = ftpClient.listFiles(path);

		for (FTPFile ftpFile : ftpFileArr) {

			if (ftpFile.isDirectory()

			&& ftpFile.getName().equalsIgnoreCase(path)) {

				flag = true;

				break;

			}

		}

		return flag;

	}

	/**
	 * 
	 * 得到某个目录下的文件名列表
	 * 
	 * @param path
	 * 
	 * @return
	 * 
	 * @throws IOException
	 */

	public List<String> getFileList(String path) throws IOException {

		String encodedPath = new String(path.getBytes("utf-8"),"iso-8859-1");

		FTPFile[] ftpFiles = ftpClient.listFiles(encodedPath);

		List<String> retList = new ArrayList<String>();

		if (ftpFiles == null || ftpFiles.length == 0) {

			return retList;

		}
		String childPath = null;
		for (FTPFile ftpFile : ftpFiles) {

			childPath = path + ftpFile.getName();
			
			if(ftpFile.isDirectory()){
				childPath += "/";
			} 
			retList.add(childPath);
			
			LOG.debug(String.format("parent path is : (%s) , child is : (%s)", path, childPath));
		}
		
		return retList;

	}
	
	/**
	 * 获取所有文件列表
	 * 说明：使用了递归算法，只适合小规模ftp
	 * @param path
	 * @return
	 * @throws IOException
	 */
	public List<String> getAllFileList(String path) throws IOException {
		
		String encodedPath = new String(path.getBytes("utf-8"),"iso-8859-1");
				
		FTPFile[] ftpFiles = ftpClient.listFiles(encodedPath);

		List<String> retList = new ArrayList<String>();

		if (ftpFiles == null || ftpFiles.length == 0) {

			return retList;

		}

		for (FTPFile ftpFile : ftpFiles) {

			if (ftpFile.isFile()) {

				retList.add(path + "/" + ftpFile.getName());
			}
			
			if(ftpFile.isDirectory()){
				
				List<String> childList = getAllFileList(path + "/" + ftpFile.getName());
				
				retList.addAll(childList);
			}
			
			LOG.debug(path + "/" + ftpFile.getName());
		}

		return retList;
	}
	
	/**
	 * 下载文件
	 * @param remote 远程文件
	 * @param localFile 本地文件
	 */
	public void downloadFile(String remote, String localFile) {
		InputStream in = null;
		try {
			String encodedPath = new String(remote.getBytes("utf-8"),"iso-8859-1");
			File temp = new File(localFile);
			FileOutputStream out = new FileOutputStream(temp,false);  
			 
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftpClient.enterLocalPassiveMode();
			in = ftpClient.retrieveFileStream(encodedPath);
			
			LOG.debug("ftp client response message :" + new String(ftpClient.getReplyString().getBytes("iso-8859-1"), "utf-8"));
			if (in != null) {
				byte[] bytes = new byte[1024];
				int c;
				while ((c = in.read(bytes)) != -1) {
					out.write(bytes, 0, c);
				}
				in.close();
				out.close();
				boolean isDo = ftpClient.completePendingCommand();
				if (!isDo) {
					throw new RuntimeException("下载失败");
				}

			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("下载失败:" + e.getMessage());
		}
	}
	
	public FtpConfiguration getConfig() {
		return config;
	}

	public static void main(String[] args) throws SocketException, IOException {
		
		String folder=System.getProperty("java.io.tmpdir");
		System.out.println(folder);
		
//		FtpUtil ftpUtil = new FtpUtil(new FtpConfiguration("192.168.2.106", 21, "infcn", "infcn", "/"));
		
//		try {
//			ftpUtil.connectServer();
//		
//			//小文件
//			String path = "/Public/soft4deploy/dotNetFx40_Full_x86_x64.exe";
//			ftpUtil.downloadFile(path, "d://dotNetFx40_Full_x86_x64.exe");
//		} catch (SocketException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} finally{
//			ftpUtil.disconnect();
//		}
		
		
		
	}
}
